/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.repair.controller;

import com.aliyun.oss.ServiceException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import lombok.AllArgsConstructor;
import javax.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.repair.dto.MalfunctionRescueSaveDTO;
import org.springblade.modules.repair.dto.RescueArriveDTO;
import org.springblade.modules.repair.dto.plan.PlanAddUserDTO;
import org.springblade.modules.repair.vo.*;
import org.springblade.modules.repair.vo.plan.PlanRescueDetailVO;
import org.springblade.modules.repair.vo.rescue.DispatcherPageReqVO;
import org.springblade.modules.repair.vo.rescue.DispatcherPageRespVO;
import org.springblade.modules.repair.vo.rescue.DispatcherStatisticsVO;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestParam;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.modules.repair.entity.MaintainMalfunctionRescue;
import org.springblade.modules.repair.wrapper.MaintainMalfunctionRescueWrapper;
import org.springblade.modules.repair.service.IMaintainMalfunctionRescueService;
import org.springblade.core.boot.ctrl.BladeController;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 救援工单明细 控制器
 *
 * @author ysq
 * @since 2023-02-25
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("repair/maintain/malfunction/rescue")
@Api(value = "救援工单明细", tags = "救援工单明细接口")
public class MaintainMalfunctionRescueController extends BladeController {

	private final IMaintainMalfunctionRescueService maintainMalfunctionRescueService;


	/**
	 * 分页 救援工单明细
	 */
	@GetMapping("/list")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "分页", notes = "传入maintainMalfunctionRescue")
	public R<IPage<MaintainMalfunctionRescueVO>> list(MaintainMalfunctionRescue maintainMalfunctionRescue, Query query) {
		IPage<MaintainMalfunctionRescue> pages = maintainMalfunctionRescueService.page(Condition.getPage(query), Condition.getQueryWrapper(maintainMalfunctionRescue));
		return R.data(MaintainMalfunctionRescueWrapper.build().pageVO(pages));
	}

	/**
	 * 新增 救援工单明细
	 */
	@PostMapping("/save")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "新增", notes = "传入maintainMalfunctionRescue")
	public R save(@Valid @RequestBody MaintainMalfunctionRescue maintainMalfunctionRescue) {
		return R.status(maintainMalfunctionRescueService.save(maintainMalfunctionRescue));
	}

	/**
	 * 修改 救援工单明细
	 */
	@PostMapping("/update")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "修改", notes = "传入maintainMalfunctionRescue")
	public R update(@Valid @RequestBody MaintainMalfunctionRescue maintainMalfunctionRescue) {
		return R.status(maintainMalfunctionRescueService.updateById(maintainMalfunctionRescue));
	}

	/**
	 * 新增或修改 救援工单明细
	 */
	@PostMapping("/submit")
	@ApiOperationSupport(order = 6)
	@ApiOperation(value = "新增或修改", notes = "传入maintainMalfunctionRescue")
	public R submit(@Valid @RequestBody MaintainMalfunctionRescue maintainMalfunctionRescue) {
		return R.status(maintainMalfunctionRescueService.saveOrUpdate(maintainMalfunctionRescue));
	}


	/**
	 * 删除 救援工单明细
	 */
	@PostMapping("/remove")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "逻辑删除", notes = "传入ids")
	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		return R.status(maintainMalfunctionRescueService.deleteLogic(Func.toLongList(ids)));
	}

	/**
	 * @return
	 * @Author lsay
	 * @Description {
	 * 获取首页救援工单弹窗列表
	 * }
	 * @Date 9:51 2023/2/28
	 * @Param
	 **/
	@GetMapping("/home/list")
	public R<List<MalfunctionRescueHomeListVO>> malfunctionRescueHomeList(Long userId, String longitude, String latitude, Date startDate, Date endDate,Boolean sortByPlanDateASC) {
		return R.data(maintainMalfunctionRescueService.malfunctionRescueHomeList(userId, longitude, latitude, startDate, endDate,sortByPlanDateASC));
	}

	/**
	 * @return
	 * @Author lsay
	 * @Description {
	 * 获取救援工单详情 及更新查看人员签到状态
	 * }
	 * @Date 9:11 2023/3/1
	 * @Param
	 **/
	@GetMapping("/detail")
	public R<MalfunctionRescueDetailVO> malfunctionRescueDetail(Long planId) {
		return R.data(maintainMalfunctionRescueService.malfunctionRescueDetail(planId));
	}

	/**
	 * @return
	 * @Author lsay
	 * @Description {
	 * 救援完成接口
	 * }
	 * @Date 9:51 2023/3/1
	 * @Param
	 **/
	@PostMapping("/finish")
	public R<Boolean> malfunctionRescueFinish(@RequestBody MalfunctionRescueSaveDTO saveDTO) {
		return R.data(maintainMalfunctionRescueService.malfunctionRescueFinish(saveDTO));
	}

	/**
	 * @Date 11:06 2023/3/1
	 * @Description {
	 * 救援工单历史分页
	 * }
	 * @Author lsay
	 **/
	@GetMapping("/history/page")
	public R<IPage<MalfunctionRescueHistoryPageVO>> historyPage(Long elevatorId, Query query) {
		IPage<MalfunctionRescueHistoryPageVO> pages = maintainMalfunctionRescueService.selectMaintainMalfunctionRescueHistoryPage(Condition.getPage(query), elevatorId);
		return R.data(pages);
	}

	@PostMapping("/arrive")
	@ApiOperation("救援已到达接口")
	@ApiOperationSupport(order = 8)
	public R<Boolean> arrive(@Valid @RequestBody RescueArriveDTO arriveRequest) {
		if (!arriveRequest.getUserId().equals(AuthUtil.getUserId())) {
			throw new ServiceException("用户信息不一致");
		}
		// 业务处理
		boolean confirmResult = maintainMalfunctionRescueService.rescueConfirm(arriveRequest);
		return R.data(confirmResult);
	}

	@GetMapping("/mapUserDetail")
	@ApiOperationSupport(order = 9)
	@ApiOperation(value = "地图-救援人员详情")
	public R<List<MapUserInfoDetailVO>> mapUserDetails(@ApiParam(value = "工单id", required = true) @RequestParam Long planId) {
		return R.data(maintainMalfunctionRescueService.mapUserDetails(planId));
	}

	@GetMapping("/rescueUserRunning")
	@ApiOperationSupport(order = 10)
	@ApiOperation(value = "判断救援人员是否在出发中")
	public R rescueUserRunning() {
		return R.data(maintainMalfunctionRescueService.rescueUserRunning(AuthUtil.getUserId()));
	}


	/**
	 * 根据电梯获取救援任务
	 *
	 * @param type       1:查询进行中的，2：历史已经完成的
	 * @param elevatorId 电梯id
	 * @return 数据集
	 */
	@GetMapping("getElevatorOfRescueInfo")
	@ApiOperation(value = "根据电梯获取救援工单")
	public R<Map<String, Object> > getElevatorOfRescueInfo(Integer type, Long elevatorId) {
		Map<String, Object> list = maintainMalfunctionRescueService.getElevatorOfRescueInfo(type, elevatorId);
		return R.data(list);
	}

	/**
	 * 新增救援工单
	 */
	@PostMapping("/add/work")
	@ApiOperationSupport(order = 11)
	@ApiOperation(value = "新增救援工单")
	public R<Long> addRescuePlan(@Valid @RequestBody MaintainMalfunctionRescue maintainMalfunctionRescue) {
		return R.data(maintainMalfunctionRescueService.addRescuePlan(maintainMalfunctionRescue));
	}

	/**
	 * 救援任务撤销操作
	 *
	 * @param planId 工单id
	 * @return 数据集
	 */
	@GetMapping("/resuceCancel")
	@ApiOperationSupport(order = 12)
	@ApiOperation(value = "救援撤销")
	public R<Boolean> rescueCancel(Long planId) {
		return R.data(maintainMalfunctionRescueService.rescueCancel(planId));
	}


	@PostMapping("/planAddUser")
	@ApiOperationSupport(order = 12)
	@ApiOperation(value = "救援工单分配人员")
	public R<Boolean> planAddUser(@Valid @RequestBody PlanAddUserDTO planAddUserDTO) {
		return R.data(maintainMalfunctionRescueService.planAddUser(planAddUserDTO));
	}

	@GetMapping("/get/rescue/detail")
	@ApiOperationSupport(order = 13)
	@ApiOperation(value = "获取救援工单详情")
	public R<PlanRescueDetailVO> getRescueDetail(@ApiParam(required = true, value = "工单id") @RequestParam Long planId) {
		return R.data(maintainMalfunctionRescueService.getRescueDetail(planId));
	}

	@GetMapping("/map/rescue/building/recently/user")
	@ApiOperationSupport(order = 13)
	@ApiOperation(value = "项目最近人员")
	public R<List<MapUserInfoVO>> mapRescueBuildingRecentlyUser(@ApiParam(required = true, value = "项目id") @RequestParam Long buildingId,
																@ApiParam(value = "交通工具") @RequestParam(required = false) List<String> vehicle,
																@ApiParam(value = "工作状态【1-空闲中，2-救援，3-维修，4-保养】") @RequestParam(required = false) List<Integer> workStatus,
																@ApiParam(value = "半径范围") @RequestParam(required = false) Integer distance,
																@ApiParam(value = "签到状态 1-已出勤，2-未出勤") @RequestParam(required = false) List<Integer> isSign,
																@ApiParam(value = "定位最后更新时间") @RequestParam(required = false) Integer searchMin,
																@ApiParam(value = "电梯id") @RequestParam(required = false) Long elevatorId,
																@ApiParam(value = "关键字") @RequestParam(required = false) String keyword) {
		return R.data(maintainMalfunctionRescueService.mapRescueBuildingRecentlyUser(buildingId, vehicle, workStatus, distance, isSign, searchMin, elevatorId, keyword));
	}

	@GetMapping("/map/rescue/building/recently/maintain/user")
	@ApiOperationSupport(order = 13)
	@ApiOperation(value = "附近项目今日保养人员")
	public R<List<MapUserInfoVO>> mapRescueBuildingRecentlyMaintainUser(@ApiParam(required = true, value = "项目id") @RequestParam Long buildingId,
																		@ApiParam(value = "交通工具") @RequestParam(required = false) List<String> vehicle,
																		@ApiParam(value = "工作状态【1-空闲中，2-救援，3-维修，4-保养】") @RequestParam(required = false) List<Integer> workStatus,
																		@ApiParam(value = "半径范围") @RequestParam(required = false) Integer distance,
																		@ApiParam(value = "签到状态 1-已出勤，2-未出勤") @RequestParam(required = false) List<Integer> isSign,
																		@ApiParam(value = "定位最后更新时间") @RequestParam(required = false) Integer searchMin,
																		@ApiParam(value = "电梯id") @RequestParam(required = false) Long elevatorId,
																		@ApiParam(value = "关键字") @RequestParam(required = false) String keyword) {
		return R.data(maintainMalfunctionRescueService.mapRescueBuildingRecentlyMaintainUser(buildingId, vehicle, workStatus, distance, isSign, searchMin, elevatorId, keyword));
	}

	@GetMapping("/map/rescue/building/recently/building/user")
	@ApiOperationSupport(order = 13)
	@ApiOperation(value = "项目附近居住人员")
	public R<List<MapUserInfoVO>> mapRescueBuildingRecentlyBulidingUser(@ApiParam(required = true, value = "项目id") @RequestParam Long buildingId,
																		@ApiParam(value = "交通工具") @RequestParam(required = false) List<String> vehicle,
																		@ApiParam(value = "工作状态【1-空闲中，2-救援，3-维修，4-保养】") @RequestParam(required = false) List<Integer> workStatus,
																		@ApiParam(value = "半径范围") @RequestParam(required = false) Integer distance,
																		@ApiParam(value = "签到状态 1-已出勤，2-未出勤") @RequestParam(required = false) List<Integer> isSign,
																		@ApiParam(value = "定位最后更新时间") @RequestParam(required = false) Integer searchMin,
																		@ApiParam(value = "电梯id") @RequestParam(required = false) Long elevatorId,
																		@ApiParam(value = "关键字") @RequestParam(required = false) String keyword) {
		return R.data(maintainMalfunctionRescueService.mapRescueBuildingRecentlyBuildingUser(buildingId, vehicle, workStatus, distance, isSign, searchMin, elevatorId, keyword));
	}

	@GetMapping("/map/rescue/user/statistics")
	@ApiOperationSupport(order = 13)
	@ApiOperation(value = "项目救援人员统计")
	public R mapRescueUserStatistics(@ApiParam(required = true, value = "项目id") @RequestParam Long buildingId) {
		List<MapUserInfoVO> recentlyUserCount = maintainMalfunctionRescueService.mapRescueBuildingRecentlyUser(buildingId, null, null, null, null, null, null,null);
		List<MapUserInfoVO> recentlyMaintainCount = maintainMalfunctionRescueService.mapRescueBuildingRecentlyMaintainUser(buildingId, null, null, null, null, null, null,null);
		List<MapUserInfoVO> recentlyBuildingCount = maintainMalfunctionRescueService.mapRescueBuildingRecentlyBuildingUser(buildingId, null, null, null, null, null, null,null);
		Map<String, Integer> map = new HashMap<>(4);
		map.put("recentlyUserCount", recentlyUserCount.size());
		map.put("recentlyMaintainCount", recentlyMaintainCount.size());
		map.put("recentlyBuildingCount", recentlyBuildingCount.size());
		return R.data(map);
	}

	@GetMapping("/dispatcher/page")
	@ApiOperationSupport(order = 14)
	@ApiOperation(value = "调度分页")
	public R<IPage<DispatcherPageRespVO>> dispatcherPage(DispatcherPageReqVO dispatcherPageReqVO, Query query){
		return R.data(maintainMalfunctionRescueService.dispatcherPage(dispatcherPageReqVO, Condition.getPage(query)));
	}

	@GetMapping("/dispatcher/statistics")
	@ApiOperationSupport(order = 14)
	@ApiOperation(value = "调度统计")
	public R<DispatcherStatisticsVO> dispatcherStatistics(){
		return R.data(maintainMalfunctionRescueService.dispatcherStatistics());
	}

	/**
	 * 救援工单详情列表
	 */
	@GetMapping("/rescue/detail/list")
	@ApiOperationSupport(order = 15)
	@ApiOperation(value = "救援工单详情列表")
	public R<List<RescueDetailVO>> rescueDetailListByElevatorId(@ApiParam(value = "项目id") @RequestParam("buildingId") Long buildingId,
																@ApiParam(value = "电梯id") @RequestParam("elevatorId") Long elevatorId) {
		return R.data(maintainMalfunctionRescueService.rescueDetailListByElevatorId(buildingId, elevatorId));
	}

	@GetMapping("/has/rela/mal/order")
	@ApiOperationSupport(order = 16)
	@ApiOperation(value = "判断是否有关联的维修单")
	public R<Boolean> hasRelaMalOrder(Long id){
		return R.data(maintainMalfunctionRescueService.hasRelaMalOrder(id));
	}

	/**
	 * 维修报障新增
	 */
	@PostMapping("/report/mal")
	@ApiOperationSupport(order = 17)
	@ApiOperation(value = "上报维修")
	public R<HashMap<String, Object>> reportMal(@Valid @RequestBody RepairWorkVO repairWorkVO) {
		return R.data(maintainMalfunctionRescueService.reportMal(repairWorkVO));
	}

	/**
	 * 催办
	 */
	@GetMapping("/reminder")
	@ApiOperationSupport(order = 18)
	@ApiOperation(value = "催办")
	public R<Boolean> reminder(@ApiParam (value = "工单id", required = true) @RequestParam Long planId) {
		return R.data(maintainMalfunctionRescueService.reminder(planId));
	}
}
